package com.encrypt.classloader;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;

/**
 * 混合型路径密钥类加载器
 * 
 * @author yiyongpeng
 * 
 */
public class MainDecryptClassLoader extends ClassLoader {

	private static File[] parsePath(String classpath) {
		String os = System.getProperty("os.name");
		String split = "\\:";
		if (os.startsWith("Win") || os.startsWith("win"))
			split = "\\;";
		String[] paths = classpath.split(split);
		File[] files = new File[paths.length];
		for (int i = 0; i < files.length; i++)
			files[i] = new File(paths[i]);
		return files;
	}

	private void init(File[] paths) {
		list = new ArrayList<IDecryptClassLoader>(2);
		for (File file : paths)
			if (file.isFile())
				try {
					list.add(new JarFileDecryptClassLoader(file
							.getAbsolutePath()));
				} catch (IOException e) {
					e.printStackTrace();
				}
			else if (file.isDirectory()) {
				list.add(new FileSystemDecryptClassLoader(file
						.getAbsolutePath()));
			} else {
				System.err.println("unkown-path:" + file.getAbsolutePath());
			}
	}

	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		IDecryptClassLoader cl;
		byte[] data;
		for (int i = 0, size = list.size(); i < size; i++) {
			cl = list.get(i);
			data = cl.loadClassData(name);
			if (data != null) {
				return defineClass(name, data, 0, data.length);
			}
		}
		return super.findClass(name);
	}

	@Override
	public URL findResource(String name) {
		for (int i = 0, size = list.size(); i < size; i++) {
			IDecryptClassLoader cl = list.get(i);
			URL url = cl.findResource(name);
			if (url != null)
				return url;
		}
		return null;
	}

	@Override
	public Enumeration<URL> findResources(String name) throws IOException {
		Vector<URL> resl = new Vector<URL>(2);
		for (int i = 0, size = list.size(); i < size; i++) {
			IDecryptClassLoader cl = list.get(i);
			URL url = cl.findResource(name);
			if (url != null)
				resl.add(url);
		}
		return resl.elements();
	}

	/**
	 * 多个路径使用分号“;”或":"分隔
	 * 
	 * @param classpath
	 */
	public MainDecryptClassLoader(String classpath) {
		init(parsePath(classpath));
	}

	public MainDecryptClassLoader(File[] path) {
		init(path);
	}

	public MainDecryptClassLoader(ClassLoader parent, File[] path) {
		super(parent);
		init(path);
	}

	protected List<IDecryptClassLoader> list;
}
